package com.zj.session;

import com.zj.enu.SqlType;
import com.zj.executor.Excecuter;
import com.zj.executor.result.SimpleResultHandler;
import com.zj.mapping.Configration;
import com.zj.mapping.MappedStatement;

import java.lang.reflect.*;
import java.util.List;

public class DefaultSqlSession implements SqlSession {
    private Configration configration;
    Excecuter excecuter;

    public DefaultSqlSession(Configration configration, Excecuter excecuter) {
        this.configration = configration;
        this.excecuter = excecuter;
    }

    @Override
    public <T> List<T> selectList(String statementId, Object... params) {
        List<Object> query = null;
        try {
            query = excecuter.query(configration.getMappedStatementMap().get(statementId), new SimpleResultHandler(), params);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return (List<T>) query;
    }

    @Override
    public <T> T selectOne(String statementId, Object... params) {
        List<Object> objects = selectList(statementId, params);
        if (objects.size() == 1) {
            return (T) objects.get(0);
        } else {
            throw new RuntimeException("查询数据为空或者过多");
        }
    }

    @Override
    public Integer insert(String statementId, Object... params) {
        try {
            return excecuter.insert(configration.getMappedStatementMap().get(statementId), params);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    @Override
    public Integer update(String statementId, Object... params) {
        try {
            return excecuter.update(configration.getMappedStatementMap().get(statementId), params);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    @Override
    public Integer delete(String statementId, Object... params) {
        try {
            return excecuter.delete(configration.getMappedStatementMap().get(statementId), params);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }


    @Override
    public <E> E getMapper(Class<E> eClass) {
        Object o = Proxy.newProxyInstance(DefaultSqlSession.class.getClassLoader(), new Class[]{eClass}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                String id = method.getName();
                String className = method.getDeclaringClass().getName();
                String statementId = className + "." + id;

                MappedStatement mappedStatement = configration.getMappedStatementMap().get(statementId);
                SqlType sqlType = mappedStatement.getSqlType();
                switch (sqlType) {
                    case DELETE:
                        return delete(statementId, args);
                    case INSERT:
                        return insert(statementId, args);
                    case UPDATE:
                        return update(statementId, args);
                    default:
                        Type genericReturnType = method.getGenericReturnType();
                        //判断返回参数是否带有泛型
                        if (genericReturnType instanceof ParameterizedType) {
                            return selectList(statementId, args);
                        } else {
                            return selectOne(statementId, args);
                        }
                }

            }
        });
        return (E) o;
    }

}
